package com.lhczf.net;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.channels.NetworkChannel;
import java.util.concurrent.atomic.AtomicLong;

public class AIOServerHandler implements SocketAcceptor, CompletionHandler<AsynchronousSocketChannel, Long> {

    private static final Logger LOGGER = LoggerFactory.getLogger(AIOServerHandler.class);
    private final AsynchronousServerSocketChannel serverChannel;
    private static final AcceptIdGenerator ID_GENERATOR = new AcceptIdGenerator();

    public AIOServerHandler(AsynchronousServerSocketChannel serverChannel) {
        this.serverChannel = serverChannel;
    }

    @Override
    public void start() {
        this.pendingAccept();
    }

    @Override
    public String getName() {
        return null;
    }

    @Override
    public int getPort() {
        return 0;
    }

    @Override
    public void completed(AsynchronousSocketChannel result, Long attachment) {
        LOGGER.info("dddddddddddddddsssssssssssssss");
        pendingAccept();
    }

    @Override
    public void failed(Throwable exc, Long attachment) {
        LOGGER.error("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
        pendingAccept();
    }
    private void pendingAccept() {
        if (this.serverChannel.isOpen()) {
            serverChannel.accept(ID_GENERATOR.getId(), this);
        }
    }
    private void accept(NetworkChannel channel, Long id) {

    }
    private static class AcceptIdGenerator {
        private static final long MAX_VALUE = 0xffffffffL;
        private AtomicLong acceptId = new AtomicLong();
        private final Object lock = new Object();

        private long getId() {
            long newValue = acceptId.getAndIncrement();
            if (newValue >= MAX_VALUE) {
                synchronized (lock) {
                    newValue = acceptId.getAndIncrement();
                    if (newValue >= MAX_VALUE) {
                        acceptId.set(0);
                    }
                }
                return acceptId.getAndDecrement();
            } else {
                return newValue;
            }
        }
    }
}
